#include "board.h"


Board::Board(MyWindow &win) : win(win), side(B), played(false), won(N), mouseDown(false), analysis(false){
	clearBoard();
	searchEngine = new AlphaBetaEngine();
	testEngine = new TestEngine();
}


Board::~Board() {
	delete searchEngine;
	delete testEngine;
}


void Board::loadBoard(const string &file) {
	board.reset(win.loadImage(file));
	distRect.x = 0;
	distRect.y = 0;
	SDL_QueryTexture(board.get(), nullptr, nullptr, &distRect.w, &distRect.h);
}

void Board::loadChessman(const string &w, const string &b) {
	auto tex = shared_ptr<SDL_Texture>(win.loadImage(b), SDL_DestroyTexture);
	chessTexures.push_back(tex);
	tex = shared_ptr<SDL_Texture>(win.loadImage(w), SDL_DestroyTexture);
	chessTexures.push_back(tex);
	chessRect.x = chessRect.y = 0;
	chessRect.w = chessRect.h = 30;

	
	SDL_Color color{ 255,0,0 };
	for (int i = 0; i < 15; ++i) {
		stringstream ss;
		ss << i;
		auto tex = shared_ptr<SDL_Texture>(win.renderText(ss.str(), TTF_FILE, color, 14), SDL_DestroyTexture);
		numberTextureVec.push_back(tex);
	}
}

void Board::render() {
	win.draw(board.get(), distRect);
	drawRowCol();
	for (auto &c : playerRecords) {
		chessRect.y = c.row * GRID_WIDTH + F_X;
		chessRect.x = c.col * GRID_WIDTH + F_Y;
		win.draw(chessTexures[playerSide].get(), chessRect);
	}
	for (auto &c : AIRecords) {
		chessRect.y = c.row * GRID_WIDTH + F_X;
		chessRect.x = c.col * GRID_WIDTH + F_Y;
		win.draw(chessTexures[AISide].get(), chessRect);
	}
	drawValue();
}


void Board::drawRowCol() {
	int x = 4, y = 15;
	for (int i = 0; i < 15; ++i) {
		win.draw(x, y + i * 35, numberTextureVec[i].get());
		if (i == 8) {
			x -= 3;
		}
	}
	x = 15, y = 4;
	for (int i = 0; i < 15; ++i) {
		win.draw(x + i * 35, y, numberTextureVec[i].get());
		if (i == 8) {
			y -= 3;
		}
	}
}


void Board::play() {
	if (checkMouseRange()) {
		if (calCell()) {
			playEnd();
		}
	}
}

bool Board::calCell() {
	if (chessmen[mouseRow][mouseCol] == N) {
		chessmen[mouseRow][mouseCol] = side;
		if (side == playerSide) {
			playerRecords.push_back(B_POINT{ mouseRow,mouseCol });
		} else if(side == AISide){
			AIRecords.push_back(B_POINT{ mouseRow,mouseCol });
		}
		return true;
	}
	return false;
}

bool Board::checkMouseRange() {
	if (!mouseDown)
		return false;
	mouseDown = false;
	int x, y;
	SDL_GetMouseState(&x, &y);
	x -= F_X;
	y -= F_Y;
	if (x < LEFT_BOUND || y < TOP_BOUND
		|| x > RIGHT_BOUND || y > BOTTOM_BOUND) {
		return false;
	}
	mouseCol = x / GRID_WIDTH;
	mouseRow = y / GRID_WIDTH;
	return true;
}

void Board::AIPlaying() {
	if (analysis) {
		play();
	} else {
		auto pos = searchEngine->searchAGoodMove(chessmen);
		chessmen[pos.row][pos.col] = AISide;
		AIRecords.push_back(pos);
		/*AI::moreStronger(chessmen, side, AIRecords);*/
		playEnd();
	}
}

void Board::exchange() { 
	if (!played) {
		return;
	}
	cout << "exchange" << endl;
	if (side == W) { 
		side = B;
	} else if (side == B) {
		side = W; 
	} 
	played = false;
}

void Board::playEnd() {
	played = true;
	if (playerRecords.size() < 5 && AIRecords.size() < 5) {
		return;
	}
	won = Judgement::isGameOver(chessmen);
}


void Board::show() {
	for (auto &a : chessmen) {
		for (auto &b : a) {
			cout << b << " ";
		}
		cout << endl;
	}
}

CHESS_COLOR Board::end() {
	return won;
}


SDL_Texture* Board::prepareForEndTexture() {
	SDL_Color color{ 255,0,0 };
	SDL_Texture *tex = nullptr;
	if (won == playerSide) {
		tex = win.renderText("YOU WIN!!!", TTF_FILE, color, 64);
	} else if (won == AISide) {
		tex = win.renderText("YOU LOSE...", TTF_FILE, color, 64);
	}
	return tex;
}


void Board::prepareForNext() {
	clearBoard();
	played = false;
	won = N;
	mouseDown = false;
	side = B;
	analysis = false;
	mouseRow = 0, mouseCol = 0;
}

void Board::clearBoard() {
	for (auto &d : chessmen) {
		for (auto &v : d) {
			v = N;
		}
	}
	playerRecords.clear();
	AIRecords.clear();
}


void Board::analysisGames() {
	cout << " AI :  I'm thinking" << endl;
	if (!analysis) {
		return;
	}
	//testEngine->setSide(side);
	testEngine->test(chessmen, side);
}

void Board::drawValue() {
	if (!analysis) {
		return;
	}
	SDL_Color color{ 0,0,255 };
	auto value = testEngine->getValue();
	//for (int i = 0; i < GRID_NUM; ++i) {
	//	for (int j = 0; j < GRID_NUM; ++j) {
	//		cout << value[i][j] << " ";
	//	}
	//	cout << endl;
	//}
	SDL_Texture *texture = nullptr;
	for (int i = 0; i < GRID_NUM; ++i) {
		for (int j = 0; j < GRID_NUM; ++j) {
			stringstream ss;
			ss << value[i][j];
			//valueTexture.reset(win.renderText(ss.str(), TTF_FILE, color, 15));
			texture = win.renderText(ss.str(), TTF_FILE, color, 15);
			int y = i * GRID_WIDTH + F_X;
			int x = j * GRID_WIDTH + F_Y;
			//cout << "x: " << x << ",  y: " << y << endl;
			//win.draw(x, y, valueTexture.get());
			win.draw(x, y, texture);
			SDL_DestroyTexture(texture);
		}
	}
	//testEngine->setAnalysis(false);
}